﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GenerateDataBaseLibrary;
using System.Data.SqlClient;
using System.Reflection;
using System.Windows.Forms;
using System.IO;
using System.Configuration;
using System.Diagnostics;

namespace GenerateDataBaseLibrary
{
    public abstract class DataSetToDataBaseMapperBase:IDataSetToDataBaseMapper
    {

        private PromptForm form;
        private FileStorageForm sform;
        TextBox field1;
        TextBox field2;
        bool flag;
        private SqlCredentials credentials;
        public  SqlCredentials Credentials
        {
            get { return credentials; }
            set { credentials = value; }
        }

        public abstract string DataBaseName
        {
            get;
            protected set;
        }
        public abstract bool GenerateFrom(System.Data.DataSet dataset);
        public abstract bool SaveTextQuery(System.Data.DataSet dataset);
        public abstract string ServerName
        {
            get;
            protected set;
        }

        protected virtual void RetrieveCredentialsFromFile(string filepath,char[]separator)
        {
            FileStream stream = new FileStream(filepath, FileMode.Open);
            StreamReader reader = new StreamReader(stream);
            string content = reader.ReadToEnd();
            reader.Close();
            string[] splitedContent = content.Split(separator);
            if (splitedContent!=null&&splitedContent.Length>=2)
            {
                Credentials.UserName = splitedContent[0];
                Credentials.Password = splitedContent[1]; 
            }
        }
  
        protected SqlConnection GetConnection(SqlCredentials credentials)
        {      
            SqlConnection connection;
            Configuration config;
            object[] attributes = credentials.GetType().GetCustomAttributes(true);
            if (attributes[0] is SqlCredentialAttribute)
            {
                SqlCredentialAttribute sqlCredentialAttribute = attributes[0] as SqlCredentialAttribute;
                switch (sqlCredentialAttribute.CredentialMode)
                {
                    case CredentialMode.Windows:
                        connection = new SqlConnection(string.Format("Data Source={0};Initial Catalog=master;Integrated Security=true;", ServerName));
                        return connection;
                    case CredentialMode.SqlSever:
                        {
                            attributes = credentials.GetType().GetCustomAttributes(true);
                            switch (sqlCredentialAttribute.CredentialSource)
                            {
                                case CredentialSource.WindowPrompt:
                                    {

                                        if (flag==false)
                                        {
                                            form = new PromptForm();
                                            Button button = form.Controls["btnCredentials"] as Button;
                                            button.Click += new EventHandler(button_Click);
                                            //Application.Run(form);  
                                            form.ShowDialog();
                                        }
                                        flag = true;
         
                                        connection = new SqlConnection(string.Format("Data Source={0};Initial Catalog=master;Integrated Security=false;" +
                                                                               @"User ID='{1}';Password='{2}'", ServerName,
                                                                               credentials.UserName,
                                                                               credentials.Password));
                                        return connection;
                                    }
                                case CredentialSource.ConfigFile:
                                    {


                                        if (flag ==false)
                                        {

                                            if (sqlCredentialAttribute.ConfigurationFilePath==string.Empty)
                                            {
                                                try
                                                {
                                                    sqlCredentialAttribute.ThrowException();
                                                }
                                                catch (SqlCredentialException)
                                                {
                                                    throw;
                                                }
                                            }

                                            SqlCredentialSection section = LoadConfiguration<SqlCredentialSection>("credentialsection");
                                            credentials.UserName = section.SqlCredential.UserName;
                                            credentials.Password = section.SqlCredential.Password;
                                            config = SetCredentialsFromConfigFile(credentials); 
                                        }
                                        flag = true;

                                        connection = new SqlConnection(string.Format("Data Source={0};Initial Catalog=master;Integrated Security=false;" +
                                                                               @"User ID='{1}';Password='{2}'", ServerName,
                                                                               credentials.UserName,
                                                                               credentials.Password));
                                        return connection;
                                    }
                                case CredentialSource.StorageFile:
                                    {
                                        if (flag == false)
                                        {
                                            sform = new FileStorageForm();
                                            Button button = sform.Controls["btnBrowse"] as Button;
                                            button.Click+=new EventHandler(sbutton_Click);
                                            sform.ShowDialog();
                                            sqlCredentialAttribute.FileStorage = sform.FileStorage;// @"D:\temp\credentials.txt"
                                            sqlCredentialAttribute.Separator = new char[] { ';',' ',',',':','.','|','/','\\','-' };
                                            if (sqlCredentialAttribute.FileStorage ==string.Empty||
                                                sqlCredentialAttribute.Separator==null||
                                                sqlCredentialAttribute.Separator.Length==0)
                                            {
                                                try
                                                {
                                                    sqlCredentialAttribute.ThrowException();
                                                }
                                                catch (SqlCredentialException caught)
                                                {
                                                    Debug.Print(caught.Message);
                                                    throw;
                                                }

                                            }
                                            RetrieveCredentialsFromFile(sqlCredentialAttribute.FileStorage, sqlCredentialAttribute.Separator); 
                                        }
                                        flag = true;
                                        connection = new SqlConnection(string.Format("Data Source={0};Initial Catalog=master;Integrated Security=false;" +
                                                                               @"User ID='{1}';Password='{2}'", ServerName,
                                                                               credentials.UserName,
                                                                               credentials.Password));

                                        return connection;
                                    }
                                default:
                                    {
                                        credentials.UserName = "sa";
                                        credentials.Password = string.Empty;
                                        break;
                                    }
                                   
                            }
                            break;
                        }
                    default:
                        connection = new SqlConnection(string.Format("Data Source={0};Initial Catalog=master;Integrated Security=true;" +
                                                                              @"User ID='{1}';Password='{2}'", ServerName,
                                                                              credentials.UserName,
                                                                              credentials.Password));
                        return connection;
                }
            }
            return null;
        }

        private Configuration SetCredentialsFromConfigFile(SqlCredentials credentials)
        {
            Configuration config;
            config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            ConfigurationSectionCollection collection =  config.Sections;
            SqlCredentialSection section = config.GetSection("sqlcredential") as SqlCredentialSection;
            if (section != null)
            {
                Credentials.UserName = section.SqlCredential.UserName;
                credentials.Password = section.SqlCredential.Password;
            }
            return config;
        }


        private static T LoadConfiguration<T>(string configurationName) where T : ConfigurationSection
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None) as Configuration;
            T section = (T)config.GetSection(configurationName);
            return section;
        }

        private void button_Click(object sender, EventArgs args)
        {
            field1 = form.Controls["txtUser"] as TextBox;
            field2 = form.Controls["txtPassword"] as TextBox;
            form.FormClosing += new FormClosingEventHandler(form_Closing);
            form.Close();
            form.Dispose();
            
        }

        void form_Closing(object sender, FormClosingEventArgs args)
        {
            if (sender is PromptForm)
            {
                if (credentials.UserName == string.Empty)
                {
                    args.Cancel = true;
                }
                credentials.UserName = field1.Text;
                credentials.Password = field2.Text;
            }
           
        }

        void sbutton_Click(object sender , EventArgs args)
        {

            OpenFileDialog dialog = new OpenFileDialog();
            dialog.FileName = "*.txt";
            if (dialog.ShowDialog()== DialogResult.OK)
            {
                TextBox txtBox = (sform.Controls["txtFileStorage"] as TextBox);
                txtBox.Text = dialog.FileName;
                sform.FileStorage = txtBox.Text;
            }
            sform.Close();
           
        }
    }//Class
}//Namespace
